package com.tanhua.server.service;

/**
 * @Author: cl
 * @Date: 2022/5/11 - 05 - 11
 * @Description:
 */

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.PageUtil;
import cn.hutool.core.util.StrUtil;
import com.github.tobato.fastdfs.domain.conn.FdfsWebServer;
import com.github.tobato.fastdfs.domain.fdfs.StorePath;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.tanhua.autoconfig.template.OssTemplate;
import com.tanhua.commons.utils.Constants;
import com.tanhua.dubbo.api.UserInfoApi;
import com.tanhua.dubbo.api.VideoApi;
import com.tanhua.model.domain.UserInfo;
import com.tanhua.model.dto.RecommendUserDto;
import com.tanhua.model.mongo.Video;
import com.tanhua.model.vo.ErrorResult;
import com.tanhua.model.vo.PageResult;
import com.tanhua.model.vo.VideoVo;
import com.tanhua.server.exception.BusinessException;
import com.tanhua.server.interceptor.UserHolder;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 小视频模块
 */
@Service
public class SmallVideosService {

    //oss
    @Autowired
    private OssTemplate ossTemplate;

    //FastDFS
    @Autowired
    private FastFileStorageClient fastFileStorageClient;

    @Autowired
    private FdfsWebServer fdfsWebServer;

    //小视频服务
    @DubboReference
    private VideoApi videoApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @DubboReference
    private UserInfoApi userInfoApi;

    /**
     * 发布小视频
     *
     * @param videoThumbnail
     * @param videoFile
     */
    public void send(MultipartFile videoThumbnail, MultipartFile videoFile) throws IOException {

        //先判断数据是否为空
        if (videoFile.isEmpty() || videoThumbnail.isEmpty()) {
            throw new BusinessException(ErrorResult.error());
        }

        //1、上传封面到oss
        String filename = videoThumbnail.getOriginalFilename();
        InputStream is = videoThumbnail.getInputStream();
        String url1 = ossTemplate.upload(filename, is);
        //2、上传小视频到fastDFS
        String name = videoFile.getOriginalFilename();
        String substring = name.substring(name.lastIndexOf(".") + 1);
        InputStream inputStream = videoFile.getInputStream();
        long size = videoFile.getSize();
        StorePath storePath = fastFileStorageClient.uploadFile(inputStream, size, substring, null);
        String url2 = fdfsWebServer.getWebServerUrl() + storePath.getFullPath();
        //3、保存封面和小视频的url到数据库
        Video video = new Video();
        video.setUserId(UserHolder.getUserId());
        video.setPicUrl(url1);
        video.setVideoUrl(url2);
        video.setText("你就是我的全世界");
        //4、调用服务上传
        String videoId = videoApi.send(video);
        if (StringUtils.isEmpty(videoId)) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    /**
     * 查询小视频
     *
     * @param page
     * @param pagesize
     * @return
     */
    public PageResult queryVideoList(Integer page, Integer pagesize) {

        //1、先查询redis中推荐的小视频
        String redisKey = Constants.VIDEOS_RECOMMEND + UserHolder.getUserId();
        String redisValue = redisTemplate.opsForValue().get(redisKey);
        //1.1进行分页处理
        List<Video> list = new ArrayList<>();
        int redisPages = 0;
        if (!StringUtils.isEmpty(redisValue)) {
            String[] split = redisValue.split(",");
            if ((page - 1) * pagesize < split.length) {
                //1.2模拟分页获取vid的集合
                List<Long> vids = Arrays.stream(split).skip((page - 1) * pagesize).limit(pagesize)
                        .map(e -> Long.valueOf(e))
                        .collect(Collectors.toList());
                //1.3调用服务根据vids查询小视频
                list = videoApi.getByVids(vids);
            }
            //1.4使用工具类统计redis总共几页数据
            redisPages = PageUtil.totalPage(split.length, pagesize);
        }
        //2、再查询数据库中的小视频
        if (list.size()<10) {
            //如果redis中没有数据了就分页查询数据库
            List<Video> page1 = videoApi.page(page - redisPages, pagesize-list.size());//页码减去redis页数=   page=1
            list.addAll(page1);
        }
        //3、获取用户的ids
        List<Long> ids = CollUtil.getFieldValues(list, "userId", Long.class);
        //4、查询用户的信息
        Map<Long, UserInfo> map = userInfoApi.selectByIds(ids, new RecommendUserDto());
        //5、封装数据
        List<VideoVo> vos = new ArrayList<>();
        for (Video video : list) {
            UserInfo userInfo = map.get(video.getUserId());
            if (userInfo != null) {
                VideoVo init = VideoVo.init(userInfo, video);
                vos.add(init);
            }
        }
        return new PageResult(page, pagesize, 0l, vos);
    }
}
